package com.zc.utilclass.dateutil.main;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @author zhangchao Java时间格式转换大全 自己封装的日期（Date）工具类
 */
public class DateUtil {
	//
	final DateFormat format0 = new SimpleDateFormat("yyyyMMdd HHmmss");
	final DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	final DateFormat format2 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
	final DateFormat format3 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
	final DateFormat format4 = new SimpleDateFormat("yyyy-MM-dd");
	final DateFormat format5 = new SimpleDateFormat("MM/dd/yyyy");
	final DateFormat format6 = new SimpleDateFormat("yyyy年MM月dd日");
	final DateFormat format7 = new SimpleDateFormat("HH:mm:ss");
	final DateFormat format8 = new SimpleDateFormat("HH时mm分ss秒");

	/**
	 * 代表第0种格式，即 yyyy-MM-dd HH:mm:ss
	 */
	public static final int DF0 = 0;
	/**
	 * 代表第1种格式，即 yyyy-MM-dd HH:mm:ss
	 */
	public static final int DF1 = 1;
	/**
	 * 代表第2种格式，即 MM/dd/yyyy HH:mm:ss
	 */
	public static final int DF2 = 2;
	/**
	 * 代表第3种格式，即 yyyy年MM月dd日 HH时mm分ss秒
	 */
	public static final int DF3 = 3;
	/**
	 * 代表第4种格式，即 yyyy-MM-dd
	 */
	public static final int DF4 = 4;
	/**
	 * 代表第5种格式，即 MM/dd/yyyy
	 */
	public static final int DF5 = 5;
	/**
	 * 代表第6种格式，即 yyyy年MM月dd日
	 */
	public static final int DF6 = 6;
	/**
	 * 代表第7种格式，即 HH:mm:ss
	 */
	public static final int DF7 = 7;
	/**
	 * 代表第8种格式，即 HH时mm分ss秒
	 */
	public static final int DF8 = 8;
	/**
	 * Constant for default style pattern. Its value is FD1.
	 */
	public static final int DEFAULT = DF1;

	// 得到当前时间 例子：Fri Sep 07 11:11:03 CST 2018 （周五 九月 07号 11:11:03 CST 2018年）
	final Date now = new Date();
	Date date = null;
	Date time = null;
	String datestr = null;
	String timestr = null;

	public DateUtil() {
	}

	public DateUtil(String date) {

	}

	// 计算某个字符在字符串中出现的次数
	private long countChar(String str, char ch) {
		long cou = 0;
		for (int i = 0; i < str.length(); i++) {
			if (ch == str.charAt(i)) {
				cou++;
			}
		}
		return cou;
	}

	/**
	 * String日期转换为Date, 必须按照这几种格式 不完善，还需修改
	 * 
	 * @param str
	 *            日期
	 * @return
	 */
	public Date string2Date2(String str) {
		// String转Date
		// str = "2007-1-18";
		try {
			if (str.contains("-") && countChar(str, '-') == 2 && str.contains(":") && countChar(str, ':') == 2) { // yyyy-MM-dd
																													// HH:mm:ss
				date = format1.parse(str);
			} else if (str.contains("/") && countChar(str, '/') == 2 && str.contains(":") && countChar(str, ':') == 2) { // MM/dd/yyyy
																															// HH:mm:ss
				date = format2.parse(str);
			} else if (str.contains("年") && str.contains("月") && str.contains("日") && str.contains("时")
					&& str.contains("分") && str.contains("秒")) { // yyyy年MM月dd日
																	// HH时mm分ss秒
				date = format3.parse(str);
			} else if (str.contains("-") && countChar(str, '-') == 2) { // yyyy-MM-dd
				date = format4.parse(str);
			} else if (str.contains("/") && countChar(str, '/') == 2) { // MM/dd/yyyy
				date = format5.parse(str);
			} else if (str.contains("年") && str.contains("月") && str.contains("日")) { // yyyy年MM月dd日
				date = format6.parse(str);
			} else if (str.contains(":") && countChar(str, ':') == 2) { // HH:mm:ss
				date = format7.parse(str);
			} else if (str.contains("时") && str.contains("分") && str.contains("秒")) { // HH时mm分ss秒
				date = format8.parse(str);
			} else {
				date = format0.parse(str);
				// System.out.println("输入语法错误！！！");
				// System.exit(0);
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	/**
	 * 判断该字符是否是日期时间连接符
	 * @param ch 
	 * @return
	 */
	private boolean isDateJoiner(char ch) {
		// 日期连接符
		if((ch=='-') || (ch=='/') || (ch=='年') || (ch=='月') || (ch=='日') || (ch=='号')) {
			return true;
		}
		// 时间连接符
		if((ch==':') || (ch=='时') || (ch=='点') || (ch=='分') || (ch=='秒')) {
			return true;
		}
		return false;
	}
	
	private boolean isCorrectDateFormat(String date) {
		char ch;
		for(int i=0; i<date.length(); i++) {
			ch = date.charAt(i);
			if(!(this.isDateJoiner(ch) || (ch>='0' && ch<='9') || (ch==' '))) {
				return false;
			}
		}
		return true;
	}
	
	/*
	 * System.exit(int status)这个方法是用来结束当前正在运行中的java虚拟机。
	 * status是非零参数，那么表示是非正常退出。
	 * System.exit(0)是正常退出程序，而System.exit(1)或者说非0表示非正常退出程序。
	 */
	
	/**
	 * 
	 * @param date 日期的字符串形式
	 * @return 标准化的日期格式 yyyy-MM-dd
	 * 日期格式： yyyy-MM-dd、yyyy/MM/dd、MM/dd/yyyy、yyyyMMdd、yyyy年MM月dd日（号）
	 */
	public String dateStringFormat(String date) {
		//日期格式： yyyy-MM-dd、yyyy/MM/dd、MM/dd/yyyy、yyyyMMdd、yyyy年MM月dd日（号）、、、、
		if(this.isCorrectDateFormat(date)) {
			
		}else {
			System.out.println("输入格式错误");
			throw new IllegalArgumentException("日期格式错误");
		}
		return "";
	}
	
	// 封装成yyyy-MM-dd HH:mm:ss 或 yyyy-MM-dd 或 HH:mm:ss
	// 我们规定，日期和时间内部不能出现空格；即空格只能出现在日期和时间中间
	// 如果是 yyyyMMdd HHmmss 或者 yyyyMMddHHmmss，必须严格按照格式
	public Date string2Date(String str) {
		//char chArr[] = str.toCharArray();
		String str1 = "";
		String str2 = "";
		//包含空格,一定既有日期，也有时间; 
		// 分为两种情况：1.有其他字符的，例如yyyy-MM-dd HH:mm:ss等 2.没其他字符，只有数字字符的，例如 yyyyMMdd HHmmss
		if(str.contains(" ")) { 
			// 先看时间
			str1 = str.substring(str.lastIndexOf(" ")+1, str.length()); //时间
			str1 = str1.replace("点", "时");
			if(str1.contains(":") || str1.contains("时") || str1.contains("分") || str1.contains("秒")) {
				// 先看时间
				//中文时间，用:代替
				if(str1.contains("时") && str1.contains("分") && (!str1.contains("秒"))) {
					// HH时mm分ss 或者 HH时mm分
					if(str1.substring(str1.lastIndexOf("分")+1, str1.length()).length() == 0) {
						// HH时mm分
						str1 += "00";
					}
				}else if(str1.contains("时") && (!str1.contains("分")) && (!str1.contains("秒"))) {
					// HH时mm 或者 HH时
					if(str1.substring(str1.lastIndexOf("时")+1, str1.length()).length() == 0) {
						// HH时
						str1 += "00:00";
					}
				}else if((!str1.contains("时")) && str1.contains("分") && (!str1.contains("秒"))) {
					// mm分ss 或者 mm分
					if(str1.substring(str1.lastIndexOf("分")+1, str1.length()).length() == 0) {
						//mm分
						str1 = "00:" + str1 + "00";
					}
				}else if((!str1.contains("时")) && (!str1.contains("分")) && str1.contains("秒")) {
					// ss秒
					str1 = "00:00:" + str1;
				}
				str1 = str1.substring(0, str1.lastIndexOf("秒"));
				str1 = str1.replace('时', '-');
				str1 = str1.replace('分', '-');
				
				// :
				if(str1.contains(":") && countChar(str1, ':') == 1) { //我们认为HH:mm
					//封装成 HH:mm:ss的格式
					str1 = str1 + ":00";
				}else if(str1.contains(":") && countChar(str1, ':') == 2) { //HH:mm:ss
					//封装成 HH:mm:ss的格式
					str1 = str1; //str.substring(str.lastIndexOf(" ")+1, str.length());
				}
			}else { // HHmmss
				// HH:mm:ss
				if(str1.length()==2) { //HH
					str1 += ":00:00";
				}else if(str1.length()==4) { // HHmm
					StringBuilder sb = new StringBuilder(str1);//构造一个StringBuilder对象
			        sb.insert(str1.length()-2, ":");//在指定的位置，插入指定的字符串
			        str1 = sb.toString();
					str1 += ":00";
				}else if(str1.length()==6) {
					StringBuilder sb = new StringBuilder(str1);//构造一个StringBuilder对象
			        sb.insert(str1.length()-2, ":");//在指定的位置，插入指定的字符串
			        sb.insert(str1.length()-4, ":");//在指定的位置，插入指定的字符串
			        str1 = sb.toString();
				}else {
					System.out.println("错误");
				}
			}
			
			//再看日期
			str2 = str.substring(0, str.indexOf(" ")); //剩下日期
			str2 = str2.replace("号", "日");
			if(str2.contains("-") || str2.contains("/") || str2.contains("年") || str2.contains("月") || str2.contains("日")) {
				// 再看日期
				//中文时间，用-代替
				if(str2.contains("年") && str2.contains("月") && (!str2.contains("日"))) {
					// yyyy年MM月dd 或者 yyyy年MM月
					if(str2.substring(str2.lastIndexOf("月")+1, str2.length()).length() == 0) {
						// yyyy年MM月
						str2 += "01";
					}
				}else if(str2.contains("年") && (!str2.contains("月")) && (!str2.contains("日"))) {
					//  yyyy年MM  或者 yyyy年
					if(str2.substring(str2.lastIndexOf("年")+1, str2.length()).length() == 0) {
						// yyyy年
						str2 += "01-01";
					}
				}else if((!str2.contains("年")) && str2.contains("月") && (!str2.contains("日"))) {
					//  MM月dd 或者 MM月
					str2 = this.getYear()+"-" + str2;
					if(str2.substring(str2.lastIndexOf("月")+1, str2.length()).length() == 0) {
						// MM月
						str2 += "01";
					}
				}else if((!str2.contains("年")) && (!str2.contains("月")) && str2.contains("日")) {
					//  dd日
					str2 = this.getYear()+"-01-" + str2;
				}
				str2 = str2.substring(0, str1.lastIndexOf("日"));
				
				// -
				if(str2.contains("-") && countChar(str2, '-') == 1) { //我们认为yyyy-MM
					//封装成 yyyy-MM-dd的格式
					str2 = str2 + "-01";
				}else if(str2.contains("-") && countChar(str2, '-') == 2) { // yyyy-MM-dd
					//封装成 yyyy-MM-dd的格式
					str2 = str2; 
				}
				// /, yyyy/MM/dd 或者 MM/dd/yyyy
				if(str2.contains("/")) {
					int len = str2.substring(0,str2.indexOf('/')).length();
					if(len >= 4) {
						// yyyy/MM/dd
						if(countChar(str2, '/') == 2) {
							str2 = str2.replace("/", "-");
						}else {
							System.out.println("错误");
						}
					}else if(len==2 || len==1) { // MM/dd/yyyy
						if(countChar(str2, '/') == 2) {
							str2 = str2.replace("/", "-");
							String myStr1 = str2.substring(str2.lastIndexOf("/")+1, str2.length());
							str2 = myStr1 + "/" + str2.substring(0, str2.lastIndexOf("/"));
						}else {
							System.out.println("错误");
						}
					}else {
						System.out.println("错误");
					}
				}
			}else { // 必须是yyyyMMdd
				if(str2.length() >= 8) { 
					StringBuilder sb = new StringBuilder(str2);//构造一个StringBuilder对象
			        sb.insert(str2.length()-2, "-");//在指定的位置，插入指定的字符串
			        sb.insert(str2.length()-4, "-");//在指定的位置，插入指定的字符串
			        str2 = sb.toString();
				}else {
					System.out.println("错误");
				}
			}
			str = str2+" "+str1;
		}else { //不包含空格, 只有日期；只有时间； yyyyMMddHHmmss
			// 只有日期
			if(str.contains("-") || str.contains("/") || str.contains("年") || str.contains("月") || str.contains("日")) {
				
			}else if(str1.contains(":") || str1.contains("时") || str1.contains("分") || str1.contains("秒")) { // 只有时间
				
			}else {
				StringBuilder sb = new StringBuilder(str);//构造一个StringBuilder对象
				if(str.length()==6) { //HHmmss
					sb.insert(str.length()-2, ":");//在指定的位置，插入指定的字符串
			        sb.insert(str.length()-4, ":");
			        str = sb.toString();
				}else if(str.length()>=8 && str.length()<14) { //yyyyMMdd
					sb.insert(str.length()-2, "-");//在指定的位置，插入指定的字符串
			        sb.insert(str.length()-4, "-");
			        str = sb.toString();
				}else if(str.length()>=14){ //yyyyMMddHHmmss
					sb.insert(str.length()-2, ":");//在指定的位置，插入指定的字符串
			        sb.insert(str.length()-4, ":");
			        sb.insert(str.length()-6, " ");
			        sb.insert(str.length()-8, "-");
			        sb.insert(str.length()-10, "-");
			        str = sb.toString();
				}else {
					System.out.println("错误");
				}
			}
		}
		try {
			date = format1.parse(str);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * Date转换为String日期
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	public String date2String(Date date) {
		String str = null;
		str = format1.format(date);
		return str;
	}

	/**
	 * Date转换为String日期
	 * 
	 * @param date
	 *            日期
	 * @param df
	 *            日期格式
	 * @return
	 */
	public String date2String(Date date, int df) {
		String str = null;
		switch (df) {
		case DF0:
			str = format0.format(date);
			break;
		case DF1:
			str = format1.format(date);
			break;
		case DF2:
			str = format2.format(date);
			break;
		case DF3:
			str = format3.format(date);
			break;
		case DF4:
			str = format4.format(date);
			break;
		case DF5:
			str = format5.format(date);
			break;
		case DF6:
			str = format6.format(date);
			break;
		case DF7:
			str = format7.format(date);
			break;
		case DF8:
			str = format8.format(date);
			break;
		default:
			str = format1.format(date);
			break;
		}
		return str;
	}

	/**
	 * 得到当前时间
	 * 
	 * @return 例子：Fri Sep 07 11:11:03 CST 2018 （周五 九月 07号 11:11:03 CST 2018年）
	 */
	public Date getNow() {
		return now;
	}

	/**
	 * 通过Date.getTime()的到的是1970年01月01日8点中以来的毫秒数
	 * 
	 * @return
	 */
	public long getTime() {
		long time = this.getNow().getTime();
		return time;
	}

	/**
	 * 获取今天的日期时间,Date转换为String日期
	 * 
	 * @return
	 */
	public String getStringNow() {
		String str = null;
		str = format1.format(now);
		return str;
	}

	/**
	 * 获取今天的日期时间,Date转换为String日期
	 * 
	 * @param df
	 *            日期格式
	 * @return 今天的日期时间
	 */
	public String getStringNow(int df) {
		String str = null;
		switch (df) {
		case DF0:
			str = format0.format(now);
			break;
		case DF1:
			str = format1.format(now);
			break;
		case DF2:
			str = format2.format(now);
			break;
		case DF3:
			str = format3.format(now);
			break;
		case DF4:
			str = format4.format(now);
			break;
		case DF5:
			str = format5.format(now);
			break;
		case DF6:
			str = format6.format(now);
			break;
		case DF7:
			str = format7.format(now);
			break;
		case DF8:
			str = format8.format(now);
			break;
		default:
			str = format1.format(now);
			break;
		}
		return str;
	}

	/**
	 * 现在的年份
	 * 
	 * @return 现在的年份
	 */
	public String getYear() {
		// yyyyMMdd HHmmss
		String dateS = format0.format(now);
		String year = dateS.substring(0, 4);
		return year;
	}

	/**
	 * 现在的月份
	 * 
	 * @return 现在的月份
	 */
	public String getMonth() {
		// yyyyMMdd HHmmss
		String dateS = format0.format(now);
		String month = dateS.substring(4, 6);
		return month;
	}

	/**
	 * 得到现在小时
	 */
	public String getHour() {
		// yyyyMMdd HHmmss
		String dateS = format0.format(now);
		String hour = dateS.substring(9, 11);
		return hour;
	}

	/**
	 * 得到现在分钟
	 */
	public String getMinute() {
		// yyyyMMdd HHmmss
		String dateS = format0.format(now);
		String minute = dateS.substring(11, 13);
		return minute;
	}

	/**
	 * 判断是否润年
	 * 
	 * @param ddate  yyyy-MM-dd
	 * @return
	 */
	public boolean isLeapYear(String ddate) {
		/**
		 * 详细设计： 1.被400整除是闰年，否则： 2.不能被4整除则不是闰年 3.能被4整除同时不能被100整除则是闰年
		 * 3.能被4整除同时能被100整除则不是闰年
		 */
		Date d = string2Date(ddate);
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(d);
		int year = gc.get(Calendar.YEAR);
		if ((year % 400) == 0)
			return true;
		else if ((year % 4) == 0) {
			if ((year % 100) == 0)
				return false;
			else
				return true;
		} else
			return false;
	}

	/**
	 * 二个小时时间间的差值,必须保证二个时间都是"HH:MM"的格式，返回字符型的分钟
	 */
	public String getTwoHour(String st1, String st2) {
		String[] kk = null;
		String[] jj = null;
		kk = st1.split(":");
		jj = st2.split(":");
		if (Integer.parseInt(kk[0]) < Integer.parseInt(jj[0]))
			return "0";
		else {
			double y = Double.parseDouble(kk[0]) + Double.parseDouble(kk[1]) / 60;
			double u = Double.parseDouble(jj[0]) + Double.parseDouble(jj[1]) / 60;
			if ((y - u) > 0)
				return y - u + "";
			else
				return "0";
		}
	}
}
